package cn.sfa.common.utils;

import java.sql.Timestamp;
import java.text.DateFormat;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
 * 
* 类名称：DateUtil   
* 类描述： 用于日期处理的工具类
* 创建人：lenovo   
* 创建时间：2011-12-13 下午09:40:12      
* @version v1.0
 */
public class DateUtil {

	public static final String DATE_FORMAT = "yyyy-MM-dd";
	public static final String DATE_FORMATS = "yyyy/MM/dd";
	public static final String SHORT_DATE_FORMAT = "yy-MM-dd";
	public static final String TIME_FORMAT = "HH:mm:ss";
	public static final String TIME_WITH_MILLISECOND_FORMAT = "HH:mm:ss.SSS";
	public static final String DATETIME_FORMAT = "yyyy-MM-dd HH:mm:ss";
	public static final String DATETIME_WITH_MILLISECOND_FORMAT = "yyyy-MM-dd HH:mm:ss.SSS";
	public static final String US_DATE_FORMAT = "MM/dd/yyyy";
	public static final String US_SHORT_DATE_FORMAT = "MM/dd/yy";
	public static final String UNIX_LONG_DATE_FORMAT = "EEE MMM dd HH:mm:ss z yyyy";
	private static String DEFAULT_DATE_FORMAT = DATE_FORMAT;
	private static String DEFAULT_DATE_FORMATS = DATE_FORMATS;

	// public static final int HOUR = Calendar.HOUR;
	// public static final int DATE = Calendar.DATE;
	// public static final int MILLISECOND = Calendar.MILLISECOND;

	public static final int SECOND = 1000;
	public static final int MINUTE = SECOND * 60;
	public static final int HOUR = MINUTE * 60;
	public static final int DAY = HOUR * 24;
	public static final int WEEK = DAY * 7;
	public static final int YEAR = DAY * 365; // or 366 ???

	/**
	 * This is the time difference between GMT time and Vietnamese time
	 */
	public static final long GMT_VIETNAM_TIME_OFFSET = HOUR * 7;

	private static DateFormat ddMMyyyyFormat = new SimpleDateFormat(
			"dd/MM/yyyy");
	private static DateFormat dateFormat = DateFormat
			.getDateInstance(DateFormat.DEFAULT);
	private static DateFormat datetimeFormat = DateFormat.getDateTimeInstance(
			DateFormat.DEFAULT, DateFormat.DEFAULT);
	/**
	 * 使用 dd/MM/yyyy 的方式格式化一个日期对象
	 * @param date 要进行格式化的 Date 对象
	 * @return 格式化日期对象后得到的字符串，形如 25/02/2008
	 */
	public static synchronized String getDateDDMMYYYY(Date date) {
		return ddMMyyyyFormat.format(date);
	}

	/**
	 * 使用默认模式格式化一个日期对象
	 * @param date 要进行格式化的 Date 对象
	 * @return 格式化日期对象后得到的字符串
	 */
	public static synchronized String formatDate(Date date) {
		return dateFormat.format(date);
	}

	/**
	 * 使用默认模式格式化一个日期时间对象
	 * @param date 要进行格式化的 Date 对象
	 * @return 格式化日期时间对象后得到的字符串
	 */
	public static synchronized String formatDateTime(Date date) {
		return datetimeFormat.format(date);
	}

	/**
	 * 获得系统年月日时分秒毫秒，以字符串"YYYY-MM-DD hh:mm:ss.SSS"返回
	 * 
	 * @return 返回"YYYY-MM-DD hh:mm:ss.SSS"字符串
	 */
	public static String getStrCurrentDetailTime() {
		String _strDate = null;

		// 日期格式
		java.text.SimpleDateFormat _dateFormat = new java.text.SimpleDateFormat(
				"yyyy-MM-dd HH:mm:ss.SSS");
		// 获得当前的时间

		java.util.Date _nowDate = new java.util.Date();
		_strDate = _dateFormat.format(_nowDate);

		return _strDate;
	}

	/**
	 * 取得越南时间？？
	 * @param date 日期对象
	 * @return date + 7 小时
	 */
	public static Date getVietnamDateFromGMTDate(Date date) {
		return new Date(date.getTime() + GMT_VIETNAM_TIME_OFFSET);
	}

	/**
	 * 将一个日期对象加上指定的小时数
	 * @param gmtDate 日期对象
	 * @param hourOffset 增加的小时数
	 * @return 增加指定小时数的日期对象
	 */
	public static Date convertGMTDate(Date gmtDate, int hourOffset) {
		return new Date(gmtDate.getTime() + hourOffset * HOUR);
	}

	/**
	 * 将一个时间戳对象增加指定的小时数
	 * @param gmtTimestamp 时间戳对象
	 * @param hourOffset 增加的小时数
	 * @return 增加指定小时数的时间戳对象
	 */
	public static Timestamp convertGMTTimestamp(Timestamp gmtTimestamp,
			int hourOffset) {
		return new Timestamp(gmtTimestamp.getTime() + hourOffset * HOUR);
	}

	/**
	 * 将一个日期对象增加指定的天数
	 * @param gmtDate 日期对象
	 * @param hourOffset 增加的天数
	 * @return 增加指定天数的日期对象
	 */
	public static Date convertGMTDateByDay(Date gmtDate, int hourOffset) {
		return new Date(gmtDate.getTime() + hourOffset * DAY);
	}

	/**
	 * 将一个日期对象增加指定的周数
	 * @param gmtDate 日期对象
	 * @param hourOffset 增加的周数
	 * @return 增加指定周数的日期对象
	 */
	public static Date convertGMTDateByWeek(Date gmtDate, int hourOffset) {
		return new Date(gmtDate.getTime() + hourOffset * WEEK);
	}

	/**
	 * 将一个日期对象增加指定的年数
	 * @param gmtDate 日期对象
	 * @param hourOffset 增加的年数
	 * @return 增加指定年数的日期对象
	 */
	public static Date convertGMTDateByyEAR(Date gmtDate, int hourOffset) {
		return new Date(gmtDate.getTime() + hourOffset * YEAR);
	}

	/**
	 * 将一个时间戳对象增加或减少指定的年数
	 * @param offsetYear 增加或减少指定的年数，单位为“年”，带“-”号时为减少
	 * @return 增加或减少指定年数的时间戳对象
	 */
	public static Timestamp getCurrentGMTTimestampExpiredYear(int offsetYear) {
		// return new Timestamp(System.currentTimeMillis() +
		// offsetYear*(365*24*60*60*1000));
		Calendar now = Calendar.getInstance();
		now.add(Calendar.YEAR, offsetYear);
		return new Timestamp(now.getTime().getTime());
	}

	/**
	 * 将一个时间戳对象增加或减少指定的月数
	 * @param offsetMonth 增加或减少指定的月数，单位为“月”，带“-”号时为减少
	 * @return 增加或减少指定月数的时间戳对象
	 */
	public static Timestamp getCurrentGMTTimestampExpiredMonth(int offsetMonth) {
		Calendar now = Calendar.getInstance();
		now.add(Calendar.MONTH, offsetMonth);
		return new Timestamp(now.getTime().getTime());
	}

	/**
	 * 将日期字符串格式化为日期对象
	 * 
	 * @param dateString
	 *            要格式化的日期字符串
	 * @param toFormat
	 *            字符串格式
	 * 
	 * @return 格式化后日期对象
	 */
	public static Date stringToDate(String dateString, String toFormat) {
		if (CommonUtil.isEmpty(dateString)) {
			return null;
		}
		SimpleDateFormat df = new SimpleDateFormat(toFormat);
		return df.parse(dateString, new ParsePosition(0));
	}

	/**
	 * 用缺省的样式将日期字符串格式化为日期对象
	 * 
	 * @param dateString
	 *            要格式化的日期字符串
	 * @return 格式化后日期对象
	 */
	public static Date stringToDate(String dateString) {
		return stringToDate(dateString, DEFAULT_DATE_FORMAT);
	}
	/**
	 * 用缺省的样式将日期字符串格式化为日期对象
	 * yyyy/MM/dd
	 * @param dateString
	 *            要格式化的日期字符串
	 * @return 格式化后日期对象
	 */
	public static Date stringToDates(String dateString){
		return stringToDate(dateString,DEFAULT_DATE_FORMATS);
	}
	
	/**
	 * 用缺省的样式将具体日期时间对象格式化为字符串
	 * 
	 * @param date
	 *            要格式化的具体日期时间对象
	 * 
	 * @return 格式化后具体日期时间字符串
	 */
	public static Date timeToString(String dateString){
		return stringToDate(dateString, DATETIME_FORMAT);
	}

	/**
	 * 将日期对象格式化为字符串
	 * 
	 * @param date
	 *            要格式化的日期对象
	 * 
	 * @param toFormat
	 *            字符串格式
	 * 
	 * @return 格式化后日期字符串
	 */
	public static String dateToString(Date date, String toFormat) {
		if (date == null) {
			return null;
		}
		SimpleDateFormat df = new SimpleDateFormat(toFormat);
		return df.format(date);
	}

	/**
	 * 用缺省的样式将日期对象格式化为字符串
	 * 
	 * @param date
	 *            要格式化的日期对对象
	 * 
	 * @return 格式化后日期字符串
	 */
	public static String dateToString(Date date) {
		return dateToString(date, DEFAULT_DATE_FORMAT);
	}

	/**
	 * 增加年，月数，天数到日期对象
	 * 
	 * @param startDate 原日期对象
	 * @param int0
	 *            要增加的字段 1:年，2：月，3：周，5：日
	 * @param int1
	 *            要增加的数量
	 * @return 增加后的日期
	 */
	public static Date add(Date startDate, int int0, int int1) {
		GregorianCalendar gCal = new GregorianCalendar();
		gCal.setTime(startDate);
		gCal.add(int0, int1);
		return toSqlDate(gCal.getTime());
	}

	/**
	 * 比较一个日期对象是否在另两个日期之
	 * 
	 * @param date
	 *            要比较的时间
	 * @param start 开始时间
	 * @param end
	 *            结束时间
	 * @return 返回是否在两个日期之间
	 */
	public static boolean isDateBetween(Date date, Date start, Date end) {
		return (start.before(date) || start.equals(date))
				&& (date.before(end) || date.equals(end));
	}

	/**
	 * 将一个日期字符串格式化为指定格式的字符串
	 * @param dateString 日期字符串
	 * @param fromFormat 对日期字符串进行转化为日期对象使用的格式
	 * @param toFormat 返回的日期字符串格式
	 * @return 使用参数 toFormat 指定的格式格式化后得到的字符串
	 */
	static public String translateDateString(String dateString,
			String fromFormat, String toFormat) {
		// parse the date string to Date
		GregorianCalendar gc = new GregorianCalendar();
		SimpleDateFormat df = new SimpleDateFormat(fromFormat);
		df.setTimeZone(gc.getTimeZone());
		df.setLenient(false);
		Date date = df.parse(dateString, new ParsePosition(0));
		// format the Date to new date string
		df = new SimpleDateFormat(toFormat);
		df.setTimeZone(gc.getTimeZone());
		String toDateString = df.format(date);
		return toDateString;
	}

	/**
	 * 使用给定的年月日创建一个 Date 对象
	 * @param year 年
	 * @param month 月
	 * @param date 日
	 * @return 使用给定的年月日创建的一个 Date 对象
	 */
	public static Date createDate(int year, int month, int date) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.set(year, month, date);
		return calendar.getTime();
	}

	/**
	 * 使用给定的年月日时分秒创建一个 Date 对象
	 * @param year 年
	 * @param month 月
	 * @param date 日
	 * @param hour 时
	 * @param minute 分
	 * @param second 秒
	 * @return 使用给定的年月日时分秒创建的一个 Date 对象
	 */
	public static Date createDate(int year, int month, int date, int hour,
			int minute, int second) {
		GregorianCalendar calendar = new GregorianCalendar();
		calendar.set(year, month, date, hour, minute, second);
		return calendar.getTime();
	}

	/**
	 * 获取某月最后一天的日期
	 * @param date 一个日期对象
	 * @return 一个形如 yyyy-MM-dd 的字符串
	 */
	public String getMonthLast(Date date) {
		Date now = new Date();
		Date nextMonth = this.add(date, 2, 1);
		String next_month = this.dateToString(nextMonth).substring(0, 8)
				+ "01 00:00:00";
		Date month_last = this.add(this.stringToDate(next_month), 6, -1);
		return this.dateToString(month_last);
	}

	/**
	 * 获取上一月。输入格式：yyyy-mm，输出格式：yyyy-mm
	 * @param month 目标月份，格式yyyy-mm
	 * @return 目标月份的上一个月，格式yyyy-mm
	 */
	public String getLastMonth(String month) {
		String lastMonth = null;
		if (Integer.parseInt(month.substring(5, 7)) > 1) {
			lastMonth = month.substring(0, 5);
			if (Integer.parseInt(month.substring(5, 7)) > 10) {

			} else {
				lastMonth += "0";
			}
			lastMonth += String
					.valueOf(Integer.parseInt(month.substring(5, 7)) - 1);
		} else if (Integer.parseInt(month.substring(5, 7)) == 1) {
			lastMonth = String
					.valueOf(Integer.parseInt(month.substring(0, 4)) - 1)
					+ "-12";
		}
		return lastMonth;
	}

	/**
	 * 两个时间之间的区段数 输入，时间1，时间2，时间增量（天数）, 时间
	 *
	 * @param start 时间1，格式：yyyy-mm-dd
	 * @param end 时间2，格式：yyyy-mm-dd
	 * @param days 时间增量（天数）
	 * @return 两个时间之间的区段数
	 */
	public int getCountBetween2Date(String start, String end, int days) {
		int count = 0;
		Date date1 = this.stringToDate(start);
		Date date2 = this.stringToDate(end);
		while (this.isDateBetween(this.add(date1, 6, count * days), date1,
				date2)) {
			count++;
		}
		if (this.isDateBetween(this.add(date1, 6, (count - 1) * days), date1,
				date2)) {
			// count++;
		}
		return count;

	}

	/**
	 * 判断输入的字符串是否可以转换为date类型
	 * 
	 * @param dateString
	 *            String,格式yyyy-mm-dd
	 * @return true-可以转换为 Date 类型，false-不可以
	 */
	public boolean ifStoD(String dateString) {
		boolean opFlag = false;
		int year = 0;// 格式化前后的年比较值
		int month = 0;// 格式化前后的月比较值
		int day = 0;// 格式化前后的日比较值
		String endStr = "";// 格式化后的字符串
		if (CommonUtil.isEmpty(dateString)) {
			opFlag = false;
		} else {
			SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			try {
				df.parse(dateString, new ParsePosition(0));
				Date ss = df.parse(dateString, new ParsePosition(0));

				if (ss != null) {
					endStr = df.format(ss);
					year = Integer.parseInt(dateString.substring(0, 4))
							- Integer.parseInt(endStr.substring(0, 4));
					month = Integer.parseInt(dateString.substring(5, 7))
							- Integer.parseInt(endStr.substring(5, 7));
					day = Integer.parseInt(dateString.substring(8, 10))
							- Integer.parseInt(endStr.substring(8, 10));
					if (year == 0 && month == 0 && day == 0) {
						opFlag = true;
					} else {
						opFlag = false;
					}

				} else {
					opFlag = false;
				}
			} catch (Exception ex) {
				ex.printStackTrace();
				opFlag = false;
			}
		}
		return opFlag;
	}

	/**
	 * 将 java.util.Date 转换成 java.sql.Date
	 * 
	 * @param date
	 *           java.util.Date 对象
	 * @return java.sql.Date 对象
	 */
	public static java.sql.Date toSqlDate(Date date) {
		if (date != null) {
			java.sql.Date returnDate = new java.sql.Date(date.getTime());
			return returnDate;
		} else {
			return null;
		}
	}

	/**
	 * 将java.sql.Date转换成java.util.Date
	 * 
	 * @param date java.sql.Date 对象
	 * @return java.util.Date 对象
	 */
	public static Date toUtilDate(java.sql.Date date) {
		if (date != null) {
			java.util.Date returnDate = new java.sql.Date(date.getTime());
			return returnDate;
		} else {
			return null;
		}

	}
	
	/**
	 * 日期转换为字符串格式
	 * @param date
	 * @return
	 */
	public static String dateToString2(Date date)
	{
		SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		String dateStr=format.format(date);
		return dateStr;
	}
	
	/**
	 * 字符串转换成日期格式
	 * @param str
	 * @return
	 */
	public static Date stringToDate2(String str)
	{
		SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Date date=null;
		try
		{
			date=format.parse(str);
		}catch(Exception e)
		{}
		return date;
	}
	/**
	 * 计算两个时间的差距是多少小时
	 * @param begin
	 * @param end
	 * @return
	 */
	public static long timeOut(String begin,String end)
	{
		long b=stringToDate2(begin).getTime();
		long e=stringToDate2(end).getTime();
		long cha=(e-b)/(60*60*1000);
		return cha;
	}
	public static void main(String[] args)
	{
		System.out.println(stringToDate2(""));
	}
	
}
